package stocks;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


import utils.QuotesManager;

import cartago.Artifact;
import cartago.OPERATION;
import cartago.ObsProperty;



/**
 *      Artifact that implements the auction. 
 */
public class StockArt extends Artifact{
            
	private ArrayList<Double> mma = new ArrayList();
	private ArrayList<Double> ifr = new ArrayList();
	private ArrayList<Double> obv = new ArrayList();
	private ArrayList<Double> estoKast = new ArrayList();
	private String simulationType = "";
	private static String OFFLINE = "OFFLINE";
	private static String ONLINE = "ONLINE";

	@OPERATION public void init(String name, String simulationType)  {
        // observable properties
    	defineObsProperty("stockName", name);
    	defineObsProperty("stockPrice", 0.0);
    	defineObsProperty("stockChange", 0.0);
        defineObsProperty("estocasticoRapido", true);
        defineObsProperty("ifr", 0.0);
        defineObsProperty("mma", 0.0);
        defineObsProperty("obv", true);
        this.simulationType = simulationType;
    }
    
    @OPERATION public void getStockPrice() throws IOException {
    	
    	// Recebe os parametros
    	String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'))	;	
    	
    	String request;
		
    	/**
    	 * Informações sobre as negociações no dia (xml)
    	 * Ex:
    	 * <PAPEL CODIGO="#VALE5" DATA="10/06/2011" DELAY="15" DESCRICAO="VALE           PNA     N1" 
    	 * HORA="18:59:11" IBOVESPA="S" MERCADO="Vista" OSCILACAO="-0,94" QUANT_NEG="11987" 
    	 * VALOR_ULTIMO="44,04"/>
    	 */
    	request = "http://www.bmfbovespa.com.br/cotacoes2000/formCotacoesMobile.asp?codsocemi="+stock;
    	
    	
        QuotesManager quotes = new QuotesManager(stock, request, "Quotes", 1);
        quotes.getStockDataFromVendor();
        
        FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		String result = "";
		while (linha != null) {
			int i = linha.indexOf("VALOR_ULTIMO");
			if (i > 0) {
				result = linha.substring(i+14, linha.indexOf("QUANT_NEG")-2);
				result = result.replace(",", ".");
				break;
			}
			linha = leitor.readLine();	
		}
		leitor.close();
		reader.close();
		
		double resultado = Double.parseDouble(result);
        	
		    	
        ObsProperty opCurrentValue  = getObsProperty("stockPrice");
        if(simulationType.equals(OFFLINE))
        {
        	double _r = opCurrentValue.doubleValues();
        	if(_r > 0.0 && resultado*1.01 > _r)
        		resultado = _r*1.005;
        	else if(_r > 0)
        		resultado = _r*0.995;
        }
        opCurrentValue.updateValue(resultado);
        
    }
    
    
    @OPERATION public void getStockChange() throws  IOException {
    	// Recebe os parametros
    	String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'))	;	
    	
    	String request;
		
    	/**
    	 * Informações sobre as negociações no dia (xml)
    	 * Ex:
    	 * <PAPEL CODIGO="#VALE5" DATA="10/06/2011" DELAY="15" DESCRICAO="VALE           PNA     N1" 
    	 * HORA="18:59:11" IBOVESPA="S" MERCADO="Vista" OSCILACAO="-0,94" QUANT_NEG="11987" 
    	 * VALOR_ULTIMO="44,04"/>
    	 */
    	request = "http://www.bmfbovespa.com.br/cotacoes2000/formCotacoesMobile.asp?codsocemi="+stock;
    	
    	
        QuotesManager quotes = new QuotesManager(stock, request,"Quotes", 1);
        quotes.getStockDataFromVendor();
        
        FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		String result = "";
		while (linha != null) {
			int i = linha.indexOf("OSCILACAO");
			if (i > 0) {
				result = linha.substring(i+11, linha.indexOf("VALOR_ULTIMO")-2);
				result = result.replace(",", ".");
				break;
			}
			linha = leitor.readLine();	
		}
		leitor.close();
		reader.close();
		
		double resultado = Double.parseDouble(result);
        ObsProperty opCurrentValue  = getObsProperty("stockChange");
        opCurrentValue.updateValue(resultado);
    }
    @OPERATION public void getEstocasticoRapido(int periodos) throws  IOException {
    	// Recebe os parametros
    	String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'))	;	
		String request;
		/**
		 * Histórico de cotações Desde 01/01/2003 até Hoje
		 */

		SimpleDateFormat diaF = new SimpleDateFormat("dd");
		SimpleDateFormat mesF = new SimpleDateFormat("MM");
		SimpleDateFormat anoF = new SimpleDateFormat("yyyy");
		Date hoje = new Date();
		String dia = diaF.format(hoje);
		String mes = mesF.format(hoje);
		String ano = anoF.format(hoje);

		request = "http://ichart.finance.yahoo.com/table.csv?s=" + stock
				+ ".SA&d=" + dia + "&e=" + mes + "&f=" + ano
				+ "&g=d&a=0&b=1&c=2003&ignore=.csv";

        QuotesManager quotes = new QuotesManager(stock, request, "Historico");
        quotes.getStockDataFromVendor();

		// calculando
		FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		int nLinha = 0;
		double minn = Double.MAX_VALUE;
		double maxn = 0;
		double valormax = 0;
		double valormin = 0;
		double ultimoFechamento = 0;
		while (nLinha < periodos) {
			linha = leitor.readLine();
			if (linha != null) {
				String[] partes = linha.split(",");
				if (nLinha == 0) {
					ultimoFechamento = Double.parseDouble(partes[4]);
				}
				valormax = Double.parseDouble(partes[2]);
				valormin = Double.parseDouble(partes[3]);
				if (valormax > maxn) {
						maxn = valormax;
				}
				if (valormin < minn) {
					minn = valormin;
				}				
			}
			nLinha++;
		}
		leitor.close();
		reader.close();
		
//		System.out.println(ultimoFechamento + " " + maxn + " " + minn);

		double resultado = ((ultimoFechamento - minn) / (maxn - minn)) * 100;
		
    	
        ObsProperty opCurrentValue  = getObsProperty("estocasticoRapido");
        opCurrentValue.updateValue(verifyBias(resultado, Strategy.K));
		
    }
    
    @OPERATION public void getIfr(int periodos) throws  IOException {
    	// Recebe os parametros
    	String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'));

		String request;
		/**
		 * Histórico de cotações Desde 01/01/2003 até Hoje
		 */

		SimpleDateFormat diaF = new SimpleDateFormat("dd");
		SimpleDateFormat mesF = new SimpleDateFormat("MM");
		SimpleDateFormat anoF = new SimpleDateFormat("yyyy");
		Date hoje = new Date();
		String dia = diaF.format(hoje);
		String mes = mesF.format(hoje);
		String ano = anoF.format(hoje);

		request = "http://ichart.finance.yahoo.com/table.csv?s=" + stock
				+ ".SA&d=" + dia + "&e=" + mes + "&f=" + ano
				+ "&g=d&a=0&b=1&c=2003&ignore=.csv";

        QuotesManager quotes = new QuotesManager(stock, request, "Historico");
        quotes.getStockDataFromVendor();

		// calculando
		FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		int nLinha = 0;
		double somatorioBaixas = 0;
		double somatorioAltas = 0;
		double primeiro = 0;
		int countBaixas = 0;
		int countAltas = 0;
		while (nLinha <= periodos) {
			double segundo = 0;
			linha = leitor.readLine();
			if (linha != null) {
				String[] partes = linha.split(",");
				segundo = Double.parseDouble(partes[4]);
				if (nLinha > 0) {
					if (primeiro < segundo) {
						somatorioBaixas += (segundo - primeiro);
						countBaixas++;
					} else if (primeiro > segundo) {
						somatorioAltas += (primeiro - segundo);
						countAltas++;
					}
				}
				primeiro = segundo;
			}
			nLinha++;
		}
		leitor.close();
		reader.close();

		double altas = (somatorioAltas / countAltas);
		double baixas = (somatorioBaixas / countBaixas);

		double resultado = 100 / (1 + (baixas/altas));
		    	
        ObsProperty opCurrentValue  = getObsProperty("ifr");
        opCurrentValue.updateValue(resultado);
    }
    
    @OPERATION public void getMma(int periodos) throws  IOException {
    	// Recebe os parametros
    	String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'));

		// Calcula a media movel aritimetica
		String request;
		/**
		 * Histórico de cotações Desde 01/01/2003 até Hoje
		 */

		SimpleDateFormat diaF = new SimpleDateFormat("dd");
		SimpleDateFormat mesF = new SimpleDateFormat("MM");
		SimpleDateFormat anoF = new SimpleDateFormat("yyyy");
		Date hoje = new Date();
		String dia = diaF.format(hoje);
		String mes = mesF.format(hoje);
		String ano = anoF.format(hoje);

		request = "http://ichart.finance.yahoo.com/table.csv?s=" + stock
				+ ".SA&d=" + dia + "&e=" + mes + "&f=" + ano
				+ "&g=d&a=0&b=1&c=2003&ignore=.csv";

        QuotesManager quotes = new QuotesManager(stock, request,"Historico");
        quotes.getStockDataFromVendor();

		// calculando
		FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		int nLinha = 0;
		double somatorio = 0;
		while (nLinha < periodos) {
			linha = leitor.readLine();
			if (linha != null) {
				String[] partes = linha.split(",");
				somatorio = somatorio + Double.parseDouble(partes[4]);
			}
			nLinha++;
		}
		leitor.close();  
		reader.close();
		
		double resultado = somatorio / periodos;
		
		ObsProperty opCurrentValue  = getObsProperty("mma");
        opCurrentValue.updateValue(resultado);
    }
    enum Strategy
    {MMA, IFR, K, OBV};
    
    private boolean verifyBias(double resultado, Strategy s){
    	switch(s)
    	{
	    	case MMA:
	    		return true;
	    	case OBV:
    			obv.add(resultado);
	    		if(obv.size() > 1 && obv.get(obv.size()-1) > obv.get(obv.size()-2))
	    			return true;
	    		return (obv.size() <= 1) ? true : false;
	    	case K:
	    		if(resultado >= 75)
	    			return true;
	    		if(resultado <= 25)
	    			return false;
	    	case IFR:
	    		return true;
    	}
    	return false;
    }

    @OPERATION public void getObv(int periodos) throws  IOException {
    	
    	// Recebe os parametros
		String stock = getObsProperty("stockName").toString();
		stock = stock.substring(stock.indexOf('(')+1, stock.indexOf(')'));
		
		String request;
		/**
		 * Histórico de cotações Desde 01/01/2003 até Hoje
		 */

		SimpleDateFormat diaF = new SimpleDateFormat("dd");
		SimpleDateFormat mesF = new SimpleDateFormat("MM");
		SimpleDateFormat anoF = new SimpleDateFormat("yyyy");
		Date hoje = new Date();
		String dia = diaF.format(hoje);
		String mes = mesF.format(hoje);
		String ano = anoF.format(hoje);

		request = "http://ichart.finance.yahoo.com/table.csv?s=" + stock
				+ ".SA&d=" + dia + "&e=" + mes + "&f=" + ano
				+ "&g=d&a=0&b=1&c=2003&ignore=.csv";

        QuotesManager quotes = new QuotesManager(stock, request,"Historico");
        quotes.getStockDataFromVendor();

		// calculando
		FileReader reader = new FileReader(quotes.getResultFile());
		BufferedReader leitor = new BufferedReader(reader);
		String linha = leitor.readLine();
		int nLinha = 0;
		double somatorioBaixas = 0;
		double somatorioAltas = 0;
		double primeiro = 0;
		double segundo = 0;
		while ((linha != null) && (!linha.trim().equals("")) && (nLinha <= periodos)) {
			linha = leitor.readLine();
			if (linha != null) {
				String[] partes = linha.split(",");
				//if (partes[5] != null) {
					segundo = Double.parseDouble(partes[4]);
					if (nLinha > 0) {
						if (primeiro < segundo) {
							somatorioBaixas += Double.parseDouble(partes[5]);
						} else if (primeiro > segundo) {
							somatorioAltas += Double.parseDouble(partes[5]);
						}
					}
					primeiro = segundo;
				//}
			}
			nLinha++;
		}
		leitor.close();
		reader.close();
		
		double resultado = (somatorioAltas - somatorioBaixas);
		
		    	
        ObsProperty opCurrentValue  = getObsProperty("obv");
        opCurrentValue.updateValue(verifyBias(resultado, Strategy.OBV));
    }
    
}

